S01-06 JavaSE-数组
[TOC]
概述
为什么需要数组
一个养鸡场有 6 只鸡,它们的体重分别是 3kg、5kg、1kg、3.4kg、2kg、50kg 。请问这六只鸡的总体重是多少?平均体重是多少?请你编一个程序(Array01.java)
思路:定义 6 个变量,加起来求总体重,进而求出平均体重。引出-> 数组
数组介绍
数组:是一种引用数据类型,用于存储固定长度的相同数据类型的元素集合。它将多个同类型的变量按连续的内存地址组织起来,通过 下标(索引) 快速访问每个元素,是处理批量同类型数据的基础结构。
即:数(数据)组(一组)就是一组数据
快速入门:养鸡场
比如,我们可以用数组来解决上一个问题,体验数组的使用:
public class Array01 {
//编写一个main方法
public static void main(String[] args) {
/*
它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg 。
请问这六只鸡的总体重是多少?平均体重是多少?
思路分析
1. 定义六个变量double , 求和得到总体重
2. 平均体重= 总体重/ 6
3. 分析传统实现的方式问题:6->600->566
4. 引出新的技术-> 使用数组来解决.
*/
// 传统方式实现(注释掉,用于对比)
// double hen1 = 3;
// double hen2 = 5;
// double hen3 = 1;
// double hen4 = 3.4;
// double hen5 = 2;
// double hen6 = 50;
// double totalWeight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
// double avgWeight = totalWeight / 6;
// System.out.println("总体重=" + totalWeight + " 平均体重=" + avgWeight);
// 用数组解决
// 老韩解读
// 1. double[] 表示是double类型的数组,数组名hens
// 2. {3, 5, 1, 3.4, 2, 50, 7.8, 88.8, 1.1, 5.6, 100} 表示数组的值/元素,依次对应数组的各个元素
double[] hens = {3, 5, 1, 3.4, 2, 50, 7.8, 88.8, 1.1, 5.6, 100};
System.out.println("===使用数组解决===");
// 老师提示:可以通过数组名.length 得到数组的大小/长度
// System.out.println("数组的长度=" + hens.length);
double totalWeight = 0;
// 遍历数组得到所有元素的和
// 老韩解读
// 1. 可以通过hens[下标] 访问数组的元素,下标从0开始(第一个元素hens[0],第二个hens[1],依次类推)
// 2. 通过for循环访问数组的所有元素
// 3. 使用变量totalWeight累积各个元素的值
for (int i = 0; i < hens.length; i++) {
// System.out.println("第" + (i+1) + "个元素的值=" + hens[i]);
totalWeight += hens[i];
}
System.out.println("总体重=" + totalWeight + " 平均体重=" + (totalWeight / hens.length));
}
}数组基础
数组初始化
方式 1:动态初始化-声明时赋值
语法:
// 语法
数据类型 数组名[] = new 数据类型[大小]
// 示例:
int a[] = new int[5]; // 创建了一个int类型数组,名字a,可存放5个int值说明:这是定义数组的一种方法,结合数组内存图理解

示例:快速入门
循环输入 5 个成绩,保存到 double 数组,并输出:
import java.util.Scanner;
public class Array02 {
public static void main(String[] args) {
// 演示动态初始化数组
// 循环输入5个成绩,保存到double数组,并输出
// 步骤
// 1. 创建double数组,大小5
// (1) 第一种动态分配方式:double scores[] = new double[5];
// (2) 第二种动态分配方式:先声明数组,再分配内存空间
double scores[]; // 声明数组,此时scores是null
scores = new double[5]; // 分配内存空间,可存放5个double数据
// 2. 循环输入成绩
Scanner myScanner = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.println("请输入第" + (i+1) + "个成绩:");
scores[i] = myScanner.nextDouble();
}
// 3. 输出数组元素
System.out.println("==数组的元素/值的情况如下:===");
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i+1) + "个元素的值=" + scores[i]);
}
}
}方式 2:动态初始化-先声明再赋值
声明数组
java// 语法 数据类型 数组名[]; 数据类型[] 数组名; // 示例 int a[]; int[] a;创建数组(分配内存)
java// 语法 数组名 = new 数据类型[大小]; // 示例 a = new int[10];
案例演示:基于前面的代码修改即可
方式 3:静态初始化
语法:
如果已知数组的元素个数和具体值,可直接使用静态初始化。
等价于:先创建指定大小的数组,再逐个给元素赋值。
数据类型 数组名[] = {元素值1, 元素值2, ..., 元素值n};示例:
// 静态初始化
int a[] = {2,5,6,7,8,89,90,34,56};
// 等价于动态初始化的如下写法
int a[] = new int[9];
a[0] = 2; a[1] = 5; a[2] = 6; a[3] = 7; a[4] = 8;
a[5] = 89; a[6] = 90; a[7] = 34; a[8] = 56;
// 养鸡场案例中的数组(静态初始化)
double hens[] = {3, 5, 1, 3.4, 2, 50};
// 等价于
double hens[] = new double[6];
hens[0] = 3; hens[1] = 5; hens[2] = 1; hens[3] = 3.4; hens[4] = 2; hens[5] = 50;数组的访问
语法:
// 语法
数组名[下标/索引/index]
// 示例:
a[2] // 访问a数组的第3个元素,数组下标从0开始数组核心特性
数组是多个相同类型数据的组合,实现对这些数据的统一管理。
数组中的元素可以是任何数据类型(包括基本类型和引用类型),但不能混用。
数组创建后如果没有赋值,会有默认值:
- 基本类型:
int 0、short 0、byte 0、long 0float 0.0、double 0.0char \u0000- ``boolean false`
- 引用类型(如 String):
null
- 基本类型:
使用数组的步骤:
- 声明数组并开辟空间
- 给数组元素赋值
- 使用数组
数组的下标从0开始。
数组下标必须在指定范围内使用(有效范围:
0~length-1),否则报下标越界异常。java// 有效下标为0-4,访问 arr[5] 会报错 int[] arr = new int[5];数组属于引用类型,数组型数据是对象(object)。
示例:验证代码
public class ArrayDetail {
//编写一个main方法
public static void main(String[] args) {
// 1. 数组元素类型必须相同(错误示例:int数组中不能放String)
// int[] arr1 = {1, 2, 3, 60, "hello"}; // 编译错误:String无法转换为int
double[] arr2 = {1.1, 2.2, 3.3, 60.6, 100}; // 正确:int自动转换为double
// 2. 数组元素可以是引用类型(示例:String数组)
String[] arr3 = {"北京", "jack", "milan"};
// 3. 数组未赋值时的默认值
short[] arr4 = new short[3];
System.out.println("=====数组arr4(未赋值的默认值)=====");
for (int i = 0; i < arr4.length; i++) {
System.out.println(arr4[i]); // 输出3个0(short类型默认值)
}
// 6. 数组下标越界演示(注释掉,避免运行报错)
// int[] arr = new int[5];
// System.out.println(arr[5]); // 运行时异常:ArrayIndexOutOfBoundsException
}
}数组应用
应用 1:创建 26 个字母数组
创建一个 char 类型的 26 个元素的数组,分别放置'A'-'Z',使用 for 循环访问所有元素并打印。
提示:char 类型支持运算('A' + 2 → 'C')
public class ArrayExercise01 {
public static void main(String[] args) {
/*
思路分析
1. 定义char数组,大小26
2. 利用'A' + i 的运算赋值(i从0到25)
3. 循环访问并打印所有元素
*/
char[] chars = new char[26];
// 赋值:A~Z
for (int i = 0; i < chars.length; i++) {
// 'A' + i 是int类型,需要强制转换为char
chars[i] = (char) ('A' + i);
}
// 输出
System.out.println("===chars数组===");
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i] + " "); // 输出:A B C ... Z
}
}
}应用 2:求数组最大值及下标
请求出数组int[] arr = {4, -1, 9, 10, 23}的最大值,并得到对应的下标。
public class ArrayExercise02 {
//编写一个main方法
public static void main(String[] args) {
/*
老韩思路分析
1. 定义目标数组
2. 假定第一个元素为最大值(max = arr[0]),下标为maxIndex=0
3. 从下标1开始遍历数组,若当前元素>max,则更新max和maxIndex
4. 遍历结束后,max即为最大值,maxIndex为对应下标
*/
int[] arr = {4, -1, 9, 10, 23};
int max = arr[0]; // 假定第一个元素是最大值
int maxIndex = 0; // 最大值的初始下标
// 从下标1开始遍历
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) { // 若当前元素大于max
max = arr[i]; // 更新最大值
maxIndex = i; // 更新最大值下标
}
}
System.out.println("max=" + max + " maxIndex=" + maxIndex); // 输出:max=23 maxIndex=4
}
}应用 3:求数组的和和平均值
基于养鸡场案例,直接通过数组遍历求和,再计算平均值(已在 Array01.java 中实现)。
数组操作
数组赋值机制
基本类型赋值
赋值的是具体的数据,两个变量相互独立,修改一个不影响另一个。
int n1 = 2;
int n2 = n1;
n2 = 80;
System.out.println("n1=" + n1); // 输出10(不受n2修改影响)
System.out.println("n2=" + n2); // 输出80引用赋值
数组默认是引用传递,赋值的是数组的地址,两个数组变量指向同一个内存空间。
修改其中一个数组的元素,会影响另一个数组。
示例:
public class ArrayAssign {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // 引用传递:arr2指向arr1的内存地址
arr2[0] = 10; // 修改arr2的元素
// 输出arr1和arr2的元素
System.out.println("====arr1的元素====");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]); // 输出:10, 2, 3(arr1的元素被修改)
}
System.out.println("====arr2的元素====");
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]); // 输出:10, 2, 3
}
}
}内存解析:
- 栈内存:存储变量(arr1、arr2),保存数组的内存地址(如 0x0011)。
- 堆内存:存储数组的实际元素(1,2,3),地址为 0x0011。
- arr1 和 arr2 都指向 0x0011,修改 arr2[0]本质是修改堆内存中数组的元素。

数组拷贝
要求:实现数组内容的复制,新数组与原数组的数据空间独立(修改新数组不影响原数组)。
public class ArrayCopy {
//编写一个main方法
public static void main(String[] args) {
// 原数组
int[] arr1 = {10, 20, 30};
// 1. 创建新数组,开辟独立的内存空间(大小与原数组一致)
int[] arr2 = new int[arr1.length];
// 2. 遍历原数组,将元素逐个拷贝到新数组
for (int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
// 修改新数组的元素(验证独立性)
arr2[0] = 100;
// 输出原数组(不受影响)
System.out.println("====arr1的元素====");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]); // 输出:10, 20, 30
}
// 输出新数组(已修改)
System.out.println("====arr2的元素====");
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]); // 输出:100, 20, 30
}
}
}数组反转
要求:将数组元素反转(如{11,22,33,44,55,66} → {66,55,44,33,22,11})
方式 1:原地反转
思路分析:
- 交换规律:
arr[i]与arr[arr.length - 1 - i]交换(i 从 0 开始)。 - 交换次数:
arr.length / 2(如 6 个元素交换 3 次,5 个元素交换 2 次)。
代码实现:
public class ArrayReverse {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66};
int temp = 0; // 辅助交换的临时变量
int len = arr.length; // 数组长度(优化:避免重复计算)
// 交换逻辑
for (int i = 0; i < len / 2; i++) {
temp = arr[len - 1 - i]; // 保存末尾元素
arr[len - 1 - i] = arr[i]; // 前面元素移到末尾
arr[i] = temp; // 末尾元素移到前面
}
// 输出反转后的数组
System.out.println("===翻转后数组===");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t"); // 输出:66 55 44 33 22 11
}
}
}方式 2:逆序赋值
思路分析:
- 创建与原数组大小相同的新数组
arr2。 - 逆序遍历原数组,将元素依次赋值给新数组的正序位置。
- 让原数组变量
arr指向新数组(原数组内存空间变为垃圾,被 JVM 回收)。

代码实现:
public class ArrayReverse02 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66};
// 创建新数组
int[] arr2 = new int[arr.length];
// 逆序遍历原数组,赋值给新数组
for (int i = arr.length - 1, j = 0; i >= 0; i--, j++) {
arr2[j] = arr[i];
}
// 原数组变量指向新数组
arr = arr2;
// 输出结果
System.out.println("====arr的元素情况=====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t"); // 输出:66 55 44 33 22 11
}
}
}数组扩容
要求:实现动态给数组添加元素,支持用户自主选择是否继续添加(ArrayAdd02.java)
需求:
- 原始数组:
int[] arr = {1,2,3}(静态分配)。 - 每次添加元素到数组末尾(如添加 4 →
{1,2,3,4})。 - 提示用户输入添加的元素,添加成功后询问是否继续(y/n)。
思路分析:
- 每次添加时,创建新数组(大小=原数组长度+1)。
- 将原数组元素拷贝到新数组。
- 新元素赋值给新数组的最后一个位置。
- 原数组变量指向新数组(完成扩容)。
- 使用
do-while循环+break控制用户输入逻辑。
代码实现:
import java.util.Scanner;
public class ArrayAdd02 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
// 初始化原数组
int[] arr = {1, 2, 3};
do {
// 1. 创建新数组(扩容+1)
int[] arrNew = new int[arr.length + 1];
// 2. 拷贝原数组元素到新数组
for (int i = 0; i < arr.length; i++) {
arrNew[i] = arr[i];
}
// 3. 接收用户输入的新元素
System.out.println("请输入你要添加的元素:");
int addNum = myScanner.nextInt();
// 4. 新元素放入新数组末尾
arrNew[arrNew.length - 1] = addNum;
// 5. 原数组指向新数组
arr = arrNew;
// 输出扩容后的数组
System.out.println("====arr扩容后元素情况====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
// 询问用户是否继续
System.out.println("\n是否继续添加?y/n");
char key = myScanner.next().charAt(0);
if (key == 'n') { // 输入n则退出
break;
}
} while (true); // 无限循环,直到用户输入n
System.out.println("你退出了添加...");
}
}练习:数组缩减
需求:有一个数组{1,2,3,4,5},提示用户是否继续缩减,每次缩减最后一个元素。当只剩最后一个元素时,提示“不能再缩减”。

算法
排序
排序介绍
排序是将多个数据按指定顺序排列的过程。
排序分类
- 内部排序:所有数据加载到内部存储器(内存)中排序,包括:
- 交换式排序法(如冒泡排序)
- 选择式排序法
- 插入式排序法
- 外部排序法:数据量过大,无法全部加载到内存,需借助外部存储(如硬盘)排序,包括:
- 合并排序法
- 直接合并排序法
冒泡排序
冒泡排序(Bubble Sorting):通过对待排序序列从后向前(下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部(类似气泡上浮)。
案例:冒泡排序实现
将无序数组{24,69,80,57,13}排成从小到大的有序数列。
思路分析:
- n 个元素需进行 n-1 轮排序(外层循环次数)。
- 每轮排序确定一个元素的最终位置(从最大到最小依次归位)。
- 每轮比较次数 = 数组长度 - 1 - 当前轮数(内层循环次数)。
- 核心逻辑:相邻元素逆序则交换。
实现步骤:
数组初始状态:[24,69,80,57,13]
- 第 1 轮排序(目标:最大数 80 移到末尾):
- 比较 24&69(不交换)→ 69&80(不交换)→ 80&57(交换 →[24,69,57,80,13])→ 80&13(交换 →[24,69,57,13,80])
- 第 2 轮排序(目标:第二大数 69 移到倒数第二):
- 比较 24&69(不交换)→ 69&57(交换 →[24,57,69,13,80])→ 69&13(交换 →[24,57,13,69,80])
- 第 3 轮排序(目标:第三大数 57 移到倒数第三):
- 比较 24&57(不交换)→ 57&13(交换 →[24,13,57,69,80])
- 第 4 轮排序(目标:第四大数 24 移到倒数第四):
- 比较 24&13(交换 →[13,24,57,69,80])

代码实现:
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13, -1, 30, 200, -110};
int temp = 0; // 辅助交换的变量
// 外层循环:控制排序轮数(n个元素需n-1轮)
for (int i = 0; i < arr.length - 1; i++) {
// 内层循环:每轮比较次数(每轮减少1次,因为末尾已排好序)
for (int j = 0; j < arr.length - 1 - i; j++) {
// 相邻元素比较,逆序则交换(从小到大排序)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
// 输出每轮排序结果
System.out.println("\n==第" + (i+1) + "轮==");
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j] + "\t");
}
}
}
}查找
在 Java 中,常用的查找方式有两种:
- 顺序查找(本章重点)
- 二分查找(后续算法讲解)
顺序查找
需求:有一个数列:{"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"},从键盘输入一个名称,判断数列中是否包含该名称。若找到,提示找到并给出下标;若未找到,提示未找到。
思路分析:
- 定义字符串数组存储目标数列。
- 接收用户输入的查找名称。
- 遍历数组,逐一比较(字符串比较用
equals方法)。 - 用变量
index标记找到的下标(初始值-1,未找到则保持-1)。
代码实现:
import java.util.Scanner;
public class SeqSearch {
public static void main(String[] args) {
// 目标数组
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
Scanner myScanner = new Scanner(System.in);
System.out.println("请输入名字:");
String findName = myScanner.next();
// 查找逻辑
int index = -1; // 标记下标(未找到为-1)
for (int i = 0; i < names.length; i++) {
// 比较输入名称与数组元素
if (findName.equals(names[i])) {
System.out.println("恭喜你找到" + findName);
System.out.println("下标为= " + i);
index = i; // 更新下标
break; // 找到后退出循环
}
}
// 未找到的提示
if (index == -1) {
System.out.println("sorry,没有找到" + findName);
}
}
}二分查找(有序数组)
需求:对有序数组{1,8,10,89,1000,1234},输入一个数,判断是否存在并求出下标(二分查找效率高于顺序查找)。
二维数组
多维数组中最常用的是二维数组,应用场景如:五子棋棋盘(行列坐标)、表格数据等。
快速入门
需求:用二维数组输出如下图形:
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0代码实现:
public class TwoDimensionalArray01 {
public static void main(String[] args) {
/*
二维数组定义:
1. 从形式上看:int[][] 表示二维数组(一维数组的每个元素是一维数组)
2. 初始化:{ {0,0,0,0,0,0}, {0,0,1,0,0,0}, {0,2,0,3,0,0}, {0,0,0,0,0,0} }
*/
int[][] arr = {
{0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 2, 0, 3, 0, 0},
{0, 0, 0, 0, 0, 0}
};
// 二维数组的关键概念
System.out.println("二维数组的元素个数(一维数组的个数)=" + arr.length); // 输出4(4个一维数组)
// 访问指定元素:第3个一维数组的第4个值(arr[2][3],下标从0开始)
System.out.println("第3个一维数组的第4个值=" + arr[2][3]); // 输出3
// 遍历二维数组(嵌套循环)
System.out.println("===二维数组图形输出===");
for (int i = 0; i < arr.length; i++) { // 遍历二维数组的每个一维数组
for (int j = 0; j < arr[i].length; j++) { // 遍历当前一维数组的每个元素
System.out.print(arr[i][j] + " ");
}
System.out.println(); // 换行
}
}
}初始化
方式 1:动态初始化-固定行列
语法:
类型[][] 数组名 = new 类型[行数][列数]示例:
public class TwoDimensionalArray02 {
public static void main(String[] args) {
// 方式1:直接初始化
// int[][] arr = new int[2][3]; // 2行3列的二维数组
// 方式2:先声明,再分配空间
int[][] arr;
arr = new int[2][3]; // 2个一维数组,每个一维数组有3个元素
arr[1][1] = 8; // 给第2行第2列的元素赋值8
// 遍历二维数组
System.out.println("===二维数组输出===");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}内存解析:
- 栈内存:
arr存储二维数组的地址(如 0x0011)。 - 堆内存:
- 二维数组(地址 0x0011)存储两个一维数组的地址(如 0x0022、0x0033)。
- 一维数组(0x0022):
[0,0,0](默认值)。 - 一维数组(0x0033):
[0,8,0](arr[1][1]赋值为 8)。

方式 3:动态初始化-列数不确定
需求:动态创建如下二维数组(每行列数不同),并输出:
i=0: 1
i=1: 2 2
i=2: 3 3 3思路分析:
- 创建二维数组时,只指定行数(3 行),不指定列数。
- 遍历每行,为每行的一维数组分配不同的列数(第 i 行分配 i+1 列)。
- 给每行的元素赋值(第 i 行的元素值为 i+1)。
代码实现:
public class TwoDimensionalArray03 {
public static void main(String[] args) {
// 创建二维数组(3行,列数不确定)
int[][] arr = new int[3][];
// 为每行分配列数并赋值
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i + 1]; // 第i行分配i+1列(0行1列,1行2列,2行3列)
// 给当前行的元素赋值
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1; // 元素值为行号+1
}
}
// 输出二维数组
System.out.println("=====arr元素=====");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println(); // 换行
}
}
}方式 4:静态初始化
语法:
类型[][] 数组名 = { {值1,值2,...}, {值1,值2,...}, ... }示例:
// 静态初始化二维数组(3行,列数分别为3、3、1)
int[][] arr = { {1,1,1}, {8,8,9}, {100} };解读:
- 二维数组
arr有 3 个元素(每个元素是一维数组)。 - 第一个一维数组:
[1, 1, 1](3 个元素)。 - 第二个一维数组:
[8, 8, 9](3 个元素)。 - 第三个一维数组:
[100](1 个元素)。
案例:二维数组求和
需求:
遍历二维数组int arr[][] = { {4,6}, {1,4,5,7}, {-2} },计算所有元素的和。
代码实现:
public class TwoDimensionalArray05 {
public static void main(String[] args) {
int arr[][] = { {4,6}, {1,4,5,7}, {-2} };
int sum = 0; // 累积和
// 嵌套循环遍历二维数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j]; // 累加每个元素
}
}
System.out.println("sum=" + sum); // 输出:4+6+1+4+5+7+(-2) = 25
}
}案例:打印杨辉三角
杨辉三角规律:
- 第 1 行有 1 个元素,第 n 行有 n 个元素。
- 每行的第一个元素和最后一个元素都是 1。
- 从第 3 行开始,中间元素的值 = 上一行同列元素 + 上一行前一列元素(
arr[i][j] = arr[i-1][j] + arr[i-1][j-1])。
代码实现:(打印 10 行杨辉三角)
public class YangHui {
public static void main(String[] args) {
int rows = 10; // 杨辉三角的行数
int[][] yangHui = new int[rows][]; // 动态初始化二维数组(行数固定,列数不确定)
// 给杨辉三角赋值
for (int i = 0; i < yangHui.length; i++) {
yangHui[i] = new int[i + 1]; // 第i行有i+1个元素
// 给每行的第一个和最后一个元素赋值1
yangHui[i][0] = 1;
yangHui[i][i] = 1;
// 给中间元素赋值(从第3行开始,i>=2)
if (i >= 2) {
for (int j = 1; j < yangHui[i].length - 1; j++) {
yangHui[i][j] = yangHui[i-1][j] + yangHui[i-1][j-1];
}
}
}
// 输出杨辉三角
System.out.println("===杨辉三角(" + rows + "行)===");
for (int i = 0; i < yangHui.length; i++) {
for (int j = 0; j < yangHui[i].length; j++) {
System.out.print(yangHui[i][j] + "\t");
}
System.out.println(); // 换行
}
}
}二维数组注意事项
一维数组的声明方式:
int[] x或int x[]。二维数组的声明方式:
int[][] y或int[] y[]或int y[][](三种都合法,推荐第一种)。二维数组由多个一维数组组成,各个一维数组的长度可以不同(列数不等的二维数组)。
java// map[0]有2个元素,map[1]有3个元素 int map[][] = { {1,2}, {3,4,5} };
练习
声明int[] x, y[];,以下选项允许通过编译的是(BE):
- a)
x[0] = y;→ 错误(int 类型不能接收 int[][]类型) - b)
y[0] = x;→ 正确(int[]类型接收 int[]类型) - c)
y[0][0] = x;→ 错误(int 类型不能接收 int[]类型) - d)
x[0][0] = y;→ 错误(x 是一维数组,x[0][0]语法错误) - e)
y[0][0] = x[0];→ 正确(int 类型接收 int 类型) - f)
x = y;→ 错误(int[]类型不能接收 int[][]类型)
本章作业
下面数组定义正确的有(BD):
- A.
String strs[] = {'a','b','c'};→ 错误(字符串数组不能用 char 字面量初始化) - B.
String[] strs = {"a","b","c"};→ 正确(静态初始化字符串数组) - C.
String[] strs = new String{"a" "b" "c"};→ 错误(语法错误:缺少逗号和右括号) - D.
String strs[] = new String[]{"a", "b","c"};→ 正确 - E.
String[] strs = new String[3]{"a", "b", "c");→ 错误(动态初始化指定长度后不能直接赋值元素)
- A.
写出结果:
javaString foo = "blue"; boolean[] bar = new boolean[2]; if (bar[0]) { foo = "green"; } System.out.println(foo); // 输出:blue(boolean数组默认值为false,if条件不成立)以下 Java 代码的输出结果为():
javaint num = 1; while (num < 10) { System.out.println(num); if (num > 5) { break; } num += 2; } // 输出:1、3、5、7(num=1→3→5→7,7>5触发break)有序数组插入元素:已知升序数组
[10,12,45,90],插入元素23后保持升序(结果[10,12,23,45,90])。实现步骤:
- 定义原数组和待插入元素:确定升序原数组和需要插入的元素。
- 查找插入位置:遍历原数组,找到第一个大于插入元素的位置(即为插入点);若元素比所有元素都大,则插入到数组末尾。
- 创建新数组:长度为原数组长度 + 1,用于存储插入后的结果。
- 复制元素并插入:将原数组中插入位置前的元素复制到新数组,放入插入元素,再复制插入位置后的元素。
- 验证结果:输出新数组,确认升序性。
代码实现:
java// 1. 定义原升序数组和待插入的元素 int[] arr = {10, 12, 45, 90}; int insertNum = 23; // 2. 查找插入位置 int insertIndex = -1; for (int i = 0; i < arr.length; i++) { // 找到第一个大于待插入元素的位置,即为插入点 if (arr[i] > insertNum) { insertIndex = i; break; } } // 若元素比所有元素都大,插入到数组末尾 if(insertIndex == -1) insertIndex = arr.length; // 3. 创建新数组并完成插入 int[] newArr = new int[arr.length + 1]; // i:新数组newArr的索引;j:原数组arr的索引 for(int i=0, j=0; i < newArr.length; i++) { if(i != insertIndex) { newArr[i] = arr[j]; j++; } else { newArr[i] = insertNum; } } // 4. 输出结果验证 System.out.println("原数组:" + Arrays.toString(arr)); System.out.println("插入元素 " + insertNum + " 后的新数组:" + Arrays.toString(newArr));数组综合操作:随机生成 10 个整数(1-100)保存到数组,实现:
- 倒序打印。
- 求平均值。
- 求最大值及下标。
- 查找是否包含数字 8。
数组引用传递练习:写出以下代码的打印结果:
javachar[] arr1 = {'a','z','b','c'}; char[] arr2 = arr1; arr1[2] = '韩'; for (int i = 0; i < arr2.length; i++) { System.out.println(arr1[i] + "," + arr2[i]); } // 输出: // a,a // z,z // 韩,韩 // c,c写出冒泡排序的代码:基于冒泡排序案例,独立实现从小到大排序。